<template>
<div class="app-container">
<!-- 顶部导航栏 -->
<header class="header">
<div class="logo">
<el-icon size="24"><Medal /></el-icon>
运动会管理系统
</div>
<div class="flex-grow"></div>
<div class="user-info">
<el-dropdown trigger="click">
<div class="user-avatar">
<el-avatar :size="40" :src="avatarUrl" icon="UserFilled"></el-avatar>
<span class="username">{{ currentUser?.realName || '管理员' }}</span>
<el-icon><ArrowDown /></el-icon>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="handleLogout">
<el-icon><SwitchButton /></el-icon>
退出登录
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</header>

<!-- 左侧导航栏 -->
<nav class="sidebar">
<div class="menu-item" :class="{ active: $route.path === '/admin' }" @click="navigateTo('/admin')">
<el-icon><Monitor /></el-icon>
<span>系统管理</span>
</div>
<div class="menu-item" :class="{ active: $route.path === '/admin/users' }" @click="navigateTo('/admin/users')">
<el-icon><User /></el-icon>
<span>用户管理</span>
</div>
<div class="menu-item" :class="{ active: $route.path === '/admin/projects' }" @click="navigateTo('/admin/projects')">
<el-icon><List /></el-icon>
<span>项目管理</span>
</div>
<div class="menu-item" :class="{ active: $route.path === '/admin/schedule' }" @click="navigateTo('/admin/schedule')">
<el-icon><Calendar /></el-icon>
<span>赛程管理</span>
</div>
<div class="menu-item active">
<el-icon><Trophy /></el-icon>
<span>成绩管理</span>
</div>
<div class="menu-item" :class="{ active: $route.path === '/admin/judges' }" @click="navigateTo('/admin/judges')">
<el-icon><Whistle /></el-icon>
<span>裁判分配</span>
</div>
</nav>

<!-- 主要内容 -->
<main class="content">
<!-- 页面标题和操作按钮 -->
<div class="page-header">
<div class="page-title">
<h1>成绩录入</h1>
<p class="page-desc">管理运动员成绩信息、支持批量录入和多种成绩类型</p>
</div>
<div class="header-actions">
<el-button type="success" @click="handleExportTemplate" :loading="exportLoading">
<el-icon><Download /></el-icon> 导出模板
</el-button>
<el-button type="warning" @click="handleBatchImport">
<el-icon><Upload /></el-icon> 批量导入
</el-button>
<el-button type="primary" @click="handleBatchRecord">
<el-icon><EditPen /></el-icon> 批量录入
</el-button>
</div>
</div>

<!-- 搜索和筛选区域 -->
<el-card class="search-card" shadow="hover">
<el-form :model="searchForm" inline>
<el-row :gutter="20">
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="项目名称">
    <el-select
v-model="searchForm.projectId"
placeholder="请选择项目"
clearable
filterable
style="width: 100%"
@change="handleProjectFilterChange">
    <el-option
v-for="project in projectOptions"
:key="project.id"
:label="project.name"
:value="project.id">
<span style="float: left">{{ project.name }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ project.type }}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="学生姓名">
    <el-input
v-model="searchForm.studentName"
placeholder="请输入学生姓名"
clearable
:prefix-icon="Search"
@keyup.enter="handleSearch">
</el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="比赛轮次">
    <el-select
v-model="searchForm.round"
placeholder="请选择轮次"
clearable
style="width: 100%">
    <el-option
v-for="round in roundOptions"
:key="round.value"
:label="round.label"
:value="round.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="成绩状态">
    <el-select
v-model="searchForm.status"
placeholder="请选择状态"
clearable
style="width: 100%">
    <el-option
v-for="status in statusOptions"
:key="status"
:label="status"
:value="status">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item>
<el-button type="primary" @click="handleSearch" :loading="tableLoading">
<el-icon><Search /></el-icon> 搜索
</el-button>
<el-button @click="handleResetSearch">
<el-icon><Refresh /></el-icon> 重置
</el-button>
<el-button type="info" @click="toggleAdvancedSearch">
<el-icon><Operation /></el-icon> {{ showAdvancedSearch ? '收起' : '高级' }}
</el-button>
</el-form-item>
</el-col>
</el-row>

<!-- 高级搜索区域 -->
<el-collapse-transition>
<div v-show="showAdvancedSearch" class="advanced-search">
<el-divider content-position="left">高级搜索</el-divider>
<el-row :gutter="20">
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="成绩类型">
    <el-select
v-model="searchForm.scoreType"
placeholder="请选择成绩类型"
clearable
style="width: 100%">
    <el-option
v-for="type in scoreTypeOptions"
:key="type.value"
:label="type.label"
:value="type.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="是否破纪录">
    <el-select
v-model="searchForm.isRecordBroken"
placeholder="请选择是否破纪录"
clearable
style="width: 100%">
<el-option label="是" value="true"></el-option>
<el-option label="否" value="false"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-form-item label="录入时间">
    <el-date-picker
v-model="searchForm.dateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
style="width: 100%"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
</div>
</el-collapse-transition>
</el-form>
</el-card>

<!-- 成绩数据表格 -->
<el-card class="table-card" shadow="hover">
<!-- 工具栏 -->
<div class="table-toolbar">
<div class="table-info">
<span class="table-title">成绩列表</span>
<el-tag type="info" size="small">共 {{ pagination.total }} 条记录</el-tag>
</div>
<div class="table-actions">
<el-button-group>
    <el-button
:size="tableSize"
@click="tableSize = 'large'"
:class="{ 'is-active': tableSize === 'large' }">
大
</el-button>
    <el-button
:size="tableSize"
@click="tableSize = 'default'"
:class="{ 'is-active': tableSize === 'default' }">
中
</el-button>
    <el-button
:size="tableSize"
@click="tableSize = 'small'"
:class="{ 'is-active': tableSize === 'small' }">
小
</el-button>
</el-button-group>
    <el-button
:icon="RefreshRight"
@click="loadTableData"
:loading="tableLoading"
circle>
</el-button>
</div>
</div>

<!-- 表格主体 -->
    <el-table
:data="tableData"
v-loading="tableLoading"
:height="tableHeight"
stripe
border
:size="tableSize"
@selection-change="handleSelectionChange"
@sort-change="handleSortChange"
style="width: 100%">
<el-table-column type="selection" width="55" align="center" fixed="left"></el-table-column>
<el-table-column prop="id" label="ID" width="80" align="center" sortable="custom"></el-table-column>
<el-table-column prop="project.name" label="项目名称" width="150" align="center" show-overflow-tooltip sortable="custom">
<template #default="scope">
<el-link type="primary" @click="handleViewProjectDetail(scope.row.project)">{{ scope.row.project.name }}</el-link>
</template>
</el-table-column>
<el-table-column prop="student.realName" label="学生姓名" width="120" align="center" show-overflow-tooltip>
<template #default="scope">
<el-link type="primary" @click="handleViewStudentDetail(scope.row.student)">{{ scope.row.student.realName }}</el-link>
</template>
</el-table-column>
<el-table-column prop="student.studentNumber" label="学号" width="120" align="center"></el-table-column>
<el-table-column prop="round" label="轮次" width="80" align="center" sortable="custom"></el-table-column>
<el-table-column prop="scoreValue" label="成绩值" width="120" align="center" sortable="custom">
<template #default="scope">
<div class="score-value">
<span class="value">{{ scope.row.scoreValue }}</span>
<span class="unit">{{ scope.row.unit }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="scoreType" label="成绩类型" width="100" align="center">
<template #default="scope">
<el-tag :type="getScoreTypeTagType(scope.row.scoreType)" size="small">
{{ getScoreTypeLabel(scope.row.scoreType) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="ranking" label="排名" width="80" align="center">
<template #default="scope">
<div v-if="scope.row.ranking" class="ranking">
<el-tag :type="getRankingTagType(scope.row.ranking)" size="small">
第{{ scope.row.ranking }}名
</el-tag>
</div>
<span v-else class="no-ranking">-</span>
</template>
</el-table-column>
<el-table-column prop="isRecordBroken" label="破纪录" width="80" align="center">
<template #default="scope">
<el-tag v-if="scope.row.isRecordBroken" type="danger" size="small">
<el-icon><Trophy /></el-icon> 破纪录
</el-tag>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column prop="status" label="状态" width="100" align="center">
<template #default="scope">
<el-tag :type="getStatusTagType(scope.row.status)" size="small">
{{ scope.row.status }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="recorder.realName" label="记录人" width="100" align="center" show-overflow-tooltip>
<template #default="scope">
<span>{{ scope.row.recorder?.realName || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="createdAt" label="录入时间" width="160" align="center" sortable="custom">
<template #default="scope">
{{ formatDateTime(scope.row.createdAt) }}
</template>
</el-table-column>
<el-table-column label="操作" width="280" align="center" fixed="right">
<template #default="scope">
<el-button-group>
<el-tooltip content="查看详情" placement="top">
    <el-button
type="primary"
:icon="View"
size="small"
@click="handleViewDetail(scope.row)">
</el-button>
</el-tooltip>
<el-tooltip content="编辑" placement="top">
    <el-button
type="primary"
:icon="Edit"
size="small"
@click="handleEdit(scope.row)">
</el-button>
</el-tooltip>
<el-tooltip content="历史记录" placement="top">
    <el-button
type="info"
:icon="Clock"
size="small"
@click="handleViewHistory(scope.row)">
</el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
    <el-button
type="danger"
:icon="Delete"
size="small"
@click="handleDelete(scope.row)">
</el-button>
</el-tooltip>
</el-button-group>
</template>
</el-table-column>
</el-table>

<!-- 分页控制 -->
<div class="pagination-container">
    <el-pagination
v-model:current-page="pagination.currentPage"
v-model:page-size="pagination.pageSize"
:page-sizes="[10, 20, 50, 100]"
:total="pagination.total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
background>
</el-pagination>
</div>

<!-- 批量操作栏 -->
<div class="batch-operations" v-if="selectedScores.length > 0">
<div class="batch-info">
<el-icon><Select /></el-icon>
<span>已选择 {{ selectedScores.length }} 项</span>
</div>
<div class="batch-actions">
<el-button-group>
<el-button type="success" @click="handleBatchAudit('有效')" :loading="batchLoading">
<el-icon><Check /></el-icon> 批量审核
</el-button>
<el-button type="warning" @click="handleBatchPublish" :loading="batchLoading">
<el-icon><Promotion /></el-icon> 批量公示
</el-button>
<el-button type="danger" @click="handleBatchDelete" :loading="batchLoading">
<el-icon><Delete /></el-icon> 批量删除
</el-button>
</el-button-group>
</div>
</div>
</el-card>
</main>

<!-- 成绩录入表单对话框 -->
    <el-dialog
:title="dialogTitle"
v-model="dialogVisible"
width="800px"
:before-close="handleDialogClose"
:close-on-click-modal="false"
destroy-on-close>
    <el-form
:model="scoreForm"
:rules="scoreFormRules"
ref="scoreFormRef"
label-width="100px"
:size="formSize">
<el-row :gutter="20">
<el-col :xs="24" :sm="12">
<el-form-item label="项目名称" prop="projectId">
    <el-select
v-model="scoreForm.projectId"
placeholder="请选择项目"
style="width: 100%"
filterable
@change="handleProjectChange">
    <el-option
v-for="project in projectOptions"
:key="project.id"
:label="project.name"
:value="project.id">
<span style="float: left">{{ project.name }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ project.type }}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12">
<el-form-item label="参赛学生" prop="studentId">
    <el-select
v-model="scoreForm.studentId"
placeholder="请选择学生"
style="width: 100%"
filterable
:disabled="!scoreForm.projectId">
    <el-option
v-for="student in studentOptions"
:key="student.id"
:label="student.realName"
:value="student.id">
<span style="float: left">{{ student.realName }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ student.studentNumber }}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :xs="24" :sm="12">
<el-form-item label="比赛轮次" prop="round">
    <el-select
v-model="scoreForm.round"
placeholder="请选择轮次"
style="width: 100%"
:disabled="!scoreForm.projectId">
    <el-option
v-for="round in roundOptions"
:key="round.value"
:label="round.label"
:value="round.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12">
<el-form-item label="成绩类型" prop="scoreType">
    <el-select
v-model="scoreForm.scoreType"
placeholder="请选择成绩类型"
style="width: 100%"
@change="handleScoreTypeChange">
    <el-option
v-for="type in scoreTypeOptions"
:key="type.value"
:label="type.label"
:value="type.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :xs="24" :sm="12">
<el-form-item label="成绩值" prop="scoreValue">
    <el-input
v-model.number="scoreForm.scoreValue"
placeholder="请输入成绩值"
type="number"
:step="getScoreStep()">
<template #append>
<el-select v-model="scoreForm.unit" placeholder="单位" style="width: 80px">
    <el-option
v-for="unit in unitOptions"
:key="unit"
:label="unit"
:value="unit">
</el-option>
</el-select>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12">
<el-form-item label="成绩状态" prop="status">
    <el-select
v-model="scoreForm.status"
placeholder="请选择状态"
style="width: 100%">
    <el-option
v-for="status in statusOptions"
:key="status"
:label="status"
:value="status">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :xs="24" :sm="12">
<el-form-item label="是否破纪录">
    <el-switch
v-model="scoreForm.isRecordBroken"
active-text="是"
inactive-text="否">
</el-switch>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12">
<el-form-item label="名次">
    <el-input-number
v-model="scoreForm.ranking"
:min="1"
:max="999"
placeholder="请输入名次"
style="width: 100%">
</el-input-number>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="备注" prop="remark">
    <el-input
v-model="scoreForm.remark"
type="textarea"
:rows="3"
placeholder="请输入备注信息">
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="handleDialogClose">取消</el-button>
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">
{{ isEdit ? '更新成绩' : '录入成绩' }}
</el-button>
</div>
</template>
</el-dialog>

<!-- 成绩详情对话框 -->
    <el-dialog
title="成绩详情"
v-model="detailDialogVisible"
width="700px">
<div v-if="currentScoreDetail" class="score-detail">
<el-descriptions :column="2" border>
<el-descriptions-item label="项目名称">{{ currentScoreDetail.project?.name }}</el-descriptions-item>
<el-descriptions-item label="项目类型">
<el-tag :type="getTypeTagType(currentScoreDetail.project?.type)">
{{ currentScoreDetail.project?.type }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="学生姓名">{{ currentScoreDetail.student?.realName }}</el-descriptions-item>
<el-descriptions-item label="学号">{{ currentScoreDetail.student?.studentNumber }}</el-descriptions-item>
<el-descriptions-item label="比赛轮次">第{{ currentScoreDetail.round }}轮</el-descriptions-item>
<el-descriptions-item label="成绩类型">
<el-tag :type="getScoreTypeTagType(currentScoreDetail.scoreType)">
{{ getScoreTypeLabel(currentScoreDetail.scoreType) }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="成绩值">{{ currentScoreDetail.scoreValue }} {{ currentScoreDetail.unit }}</el-descriptions-item>
<el-descriptions-item label="名次">
<span v-if="currentScoreDetail.ranking">第{{ currentScoreDetail.ranking }}名</span>
<span v-else>-</span>
</el-descriptions-item>
<el-descriptions-item label="是否破纪录">
<el-tag v-if="currentScoreDetail.isRecordBroken" type="danger">
<el-icon><Trophy /></el-icon> 破纪录
</el-tag>
<span v-else>否</span>
</el-descriptions-item>
<el-descriptions-item label="成绩状态">
<el-tag :type="getStatusTagType(currentScoreDetail.status)">
{{ currentScoreDetail.status }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="记录人">{{ currentScoreDetail.recorder?.realName || '-' }}</el-descriptions-item>
<el-descriptions-item label="录入时间">{{ formatDateTime(currentScoreDetail.createdAt) }}</el-descriptions-item>
<el-descriptions-item label="更新时间">{{ formatDateTime(currentScoreDetail.updatedAt) }}</el-descriptions-item>
<el-descriptions-item label="备注" :span="2">
<div class="remark-content">{{ currentScoreDetail.remark || '-' }}</div>
</el-descriptions-item>
</el-descriptions>
</div>
</el-dialog>

<!-- 批量录入对话框 -->
    <el-dialog
title="批量录入成绩"
v-model="batchRecordDialogVisible"
width="900px"
:before-close="handleBatchRecordDialogClose"
:close-on-click-modal="false"
destroy-on-close>
    <el-form
:model="batchRecordForm"
:rules="batchRecordFormRules"
ref="batchRecordFormRef"
label-width="100px"
:size="formSize">
<el-row :gutter="20">
<el-col :xs="24" :sm="12">
<el-form-item label="项目名称" prop="projectId">
    <el-select
v-model="batchRecordForm.projectId"
placeholder="请选择项目"
style="width: 100%"
filterable
@change="handleBatchProjectChange">
    <el-option
v-for="project in projectOptions"
:key="project.id"
:label="project.name"
:value="project.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12">
<el-form-item label="比赛轮次" prop="round">
    <el-select
v-model="batchRecordForm.round"
placeholder="请选择轮次"
style="width: 100%"
:disabled="!batchRecordForm.projectId">
    <el-option
v-for="round in roundOptions"
:key="round.value"
:label="round.label"
:value="round.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>

<!-- 批量录入表格 -->
    <el-table
:data="batchRecordForm.scores"
border
style="width: 100%; margin-top: 20px"
max-height="400">
<el-table-column type="index" width="50" label="序号" align="center"></el-table-column>
<el-table-column prop="studentName" label="学生姓名" width="120" align="center">
<template #default="scope">
    <el-select
v-model="scope.row.studentId"
placeholder="选择学生"
filterable
size="small"
style="width: 100%"
@change="handleBatchStudentChange(scope.row)">
    <el-option
v-for="student in batchStudentOptions"
:key="student.id"
:label="student.realName"
:value="student.id">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="scoreValue" label="成绩值" width="150" align="center">
<template #default="scope">
    <el-input
v-model.number="scope.row.scoreValue"
placeholder="请输入成绩"
type="number"
size="small">
<template #append>
<span>{{ batchRecordForm.unit }}</span>
</template>
</el-input>
</template>
</el-table-column>
<el-table-column prop="ranking" label="名次" width="100" align="center">
<template #default="scope">
    <el-input-number
v-model="scope.row.ranking"
:min="1"
:max="999"
size="small"
style="width: 100%">
</el-input-number>
</template>
</el-table-column>
<el-table-column prop="isRecordBroken" label="破纪录" width="80" align="center">
<template #default="scope">
    <el-switch
v-model="scope.row.isRecordBroken"
size="small">
</el-switch>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" min-width="150" align="center">
<template #default="scope">
    <el-input
v-model="scope.row.remark"
placeholder="备注"
size="small">
</el-input>
</template>
</el-table-column>
<el-table-column label="操作" width="80" align="center">
<template #default="scope">
    <el-button
type="danger"
:icon="Delete"
size="small"
@click="handleRemoveBatchScore(scope.$index)">
</el-button>
</template>
</el-table-column>
</el-table>

<div style="margin-top: 20px; text-align: center;">
<el-button type="primary" @click="handleAddBatchScore">
<el-icon><Plus /></el-icon> 添加成绩
</el-button>
</div>

<template #footer>
<div class="dialog-footer">
<el-button @click="handleBatchRecordDialogClose">取消</el-button>
<el-button type="primary" @click="handleBatchRecordSubmit" :loading="batchSubmitLoading">
批量录入
</el-button>
</div>
</template>
</el-dialog>

<!-- 批量导入对话框 -->
    <el-dialog
title="批量导入成绩"
v-model="importDialogVisible"
width="600px"
:before-close="handleImportDialogClose">
<div class="import-content">
    <el-alert
title="导入说明"
type="info"
:closable="false"
style="margin-bottom: 20px">
<template #default>
<p>1. 请先下载模板文件，按照模板格式填写数据</p>
<p>2. 支持Excel格式(.xlsx, .xls)</p>
<p>3. 文件大小不超过10MB</p>
</template>
</el-alert>

    <el-upload
ref="uploadRef"
:auto-upload="false"
:on-change="handleFileChange"
:before-upload="beforeUpload"
:file-list="fileList"
accept=".xlsx,.xls">
<el-button type="primary">选取文件</el-button>
<template #tip>
<div class="el-upload__tip">只能上传xlsx/xls文件，且不超过10MB</div>
</template>
</el-upload>
</div>

<template #footer>
<div class="dialog-footer">
<el-button @click="handleImportDialogClose">取消</el-button>
<el-button type="primary" @click="submitUpload" :loading="uploadLoading">
开始导入
</el-button>
</div>
</template>
</el-dialog>

<!-- 成绩历史记录对话框 -->
    <el-dialog
title="成绩修改历史"
v-model="historyDialogVisible"
width="800px">
<el-timeline>
    <el-timeline-item
v-for="(history, index) in scoreHistory"
:key="index"
:timestamp="formatDateTime(history.createdAt)"
placement="top">
<el-card>
<h4>{{ history.operation }}</h4>
<p>
<strong>操作人：</strong>{{ history.operator?.realName }}<br>
<strong>修改内容：</strong>{{ history.changes }}<br>
<strong>备注：</strong>{{ history.remark || '无' }}
</p>
</el-card>
</el-timeline-item>
</el-timeline>
<template #footer>
<div class="dialog-footer">
<el-button @click="historyDialogVisible = false">关闭</el-button>
</div>
</template>
</el-dialog>
</div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, onBeforeUnmount } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
// 图标组件
Medal, User, Monitor, List, Calendar, Whistle, ArrowDown, SwitchButton,
Download, Upload, EditPen, Search, Refresh, Operation, View,
Edit, Delete, RefreshRight, Check, Trophy, Clock, Plus,
Promotion
} from '@element-plus/icons-vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'

// 导入API接口
import {
getScorePage, getScoreById, addScore, updateScore, deleteScore,
batchDeleteScores, batchImportScores, batchAuditScores, batchPublishScores,
exportScoreTemplate, getScoreUnits, getScoreStatuses,
getScoreHistory
} from '@/api/score'
import { getProjectPage } from '@/api/project'
import { getEnrollmentsByProjectId } from '@/api/enrollment'

// 路由和状态管理
const router = useRouter()
const store = useStore()

// 响应式数据
// eslint-disable-next-line no-unused-vars
const loading = ref(false)
const tableLoading = ref(false)
const submitLoading = ref(false)
const exportLoading = ref(false)
const batchLoading = ref(false)
const batchSubmitLoading = ref(false)
const uploadLoading = ref(false)
const dialogVisible = ref(false)
const detailDialogVisible = ref(false)
const batchRecordDialogVisible = ref(false)
const importDialogVisible = ref(false)
const historyDialogVisible = ref(false)
const showAdvancedSearch = ref(false)
const isEdit = ref(false)
const tableSize = ref('default')
const formSize = ref('default')

// 表格高度
const tableHeight = ref(600)

// 搜索表单
const searchForm = reactive({
projectId: null,
studentName: '',
status: '',
round: null,
scoreType: '',
isRecordBroken: '',
dateRange: null,
sortBy: '',
sortOrder: ''
})

// 分页信息
const pagination = reactive({
currentPage: 1,
pageSize: 10,
total: 0
})

// 表格数据
const tableData = ref([])
const selectedScores = ref([])

// 成绩详情
const currentScoreDetail = ref(null)

// 成绩历史记录
const scoreHistory = ref([])

// 当前用户信息
const currentUser = computed(() => {
  try {
    // 优先从store获取用户信息
    if (store.state && store.state.user) {
      return store.state.user
    }
    // 从localStorage获取用户信息
    const userStr = localStorage.getItem('user')
    if (userStr) {
      return JSON.parse(userStr)
    }
    // 返回默认用户信息
    return { realName: '管理员' }
  } catch (error) {
    console.error('获取用户信息失败:', error)
    return { realName: '管理员' }
  }
})

// 默认头像URL
const avatarUrl = computed(() => '/img/jstu1.webp')

// 选项数据
const projectOptions = ref([])
const studentOptions = ref([])
const batchStudentOptions = ref([])
const roundOptions = ref([])
const unitOptions = ref([])
const statusOptions = ref([])
const scoreTypeOptions = ref([
{ label: '时间', value: 'time' },
{ label: '距离', value: 'distance' },
{ label: '得分', value: 'score' },
{ label: '名次', value: 'ranking' }
])

// 成绩表单
const scoreForm = reactive({
id: null,
projectId: null,
studentId: null,
round: 1,
scoreValue: null,
scoreType: 'time',
unit: '秒',
status: '有效',
ranking: null,
isRecordBroken: false,
remark: ''
})

// 批量录入表单
const batchRecordForm = reactive({
projectId: null,
round: 1,
unit: '秒',
scores: []
})

// 上传文件
const fileList = ref([])

// 对话框标题
const dialogTitle = computed(() => isEdit.value ? '编辑成绩' : '录入成绩')

// 表单引用
const scoreFormRef = ref(null)
const batchRecordFormRef = ref(null)
const uploadRef = ref(null)

// 表单验证规则
const scoreFormRules = reactive({
projectId: [
{ required: true, message: '请选择项目', trigger: 'change' }
],
studentId: [
{ required: true, message: '请选择学生', trigger: 'change' }
],
round: [
{ required: true, message: '请选择轮次', trigger: 'change' }
],
scoreValue: [
{ required: true, message: '请输入成绩值', trigger: 'blur' },
{ type: 'number', message: '成绩值必须为数字', trigger: 'blur' }
],
scoreType: [
{ required: true, message: '请选择成绩类型', trigger: 'change' }
],
status: [
{ required: true, message: '请选择状态', trigger: 'change' }
]
})

// 批量录入表单验证规则
const batchRecordFormRules = reactive({
projectId: [
{ required: true, message: '请选择项目', trigger: 'change' }
],
round: [
{ required: true, message: '请选择轮次', trigger: 'change' }
]
})

// 设置表格高度
const setTableHeight = () => {
tableHeight.value = window.innerHeight - 350
}

// 切换高级搜索
const toggleAdvancedSearch = () => {
showAdvancedSearch.value = !showAdvancedSearch.value
}

// 初始化数据
const initData = async () => {
await loadProjectOptions()
await loadUnitOptions()
await loadStatusOptions()
loadTableData()
}

// 加载项目选项
const loadProjectOptions = async () => {
try {
const response = await getProjectPage(1, 1000, { status: '进行中' })
if (response.code === 200) {
projectOptions.value = response.data.records
}
} catch (error) {
console.error('获取项目列表失败:', error)
}
}

// 加载学生选项
const loadStudentOptions = async (projectId) => {
if (!projectId) {
studentOptions.value = []
return
}

try {
const response = await getEnrollmentsByProjectId(projectId)
if (response.code === 200) {
studentOptions.value = response.data.map(enrollment => enrollment.student)
}
} catch (error) {
console.error('获取学生列表失败:', error)
studentOptions.value = []
}
}

// 加载单位选项
const loadUnitOptions = async () => {
try {
const response = await getScoreUnits()
if (response.code === 200) {
unitOptions.value = response.data
} else {
// 默认单位选项
unitOptions.value = ['秒', '米', '分', '个', '次']
}
} catch (error) {
console.error('获取单位列表失败:', error)
// 默认单位选项
unitOptions.value = ['秒', '米', '分', '个', '次']
}
}

// 加载状态选项
const loadStatusOptions = async () => {
try {
const response = await getScoreStatuses()
if (response.code === 200) {
statusOptions.value = response.data
} else {
// 默认状态选项
statusOptions.value = ['有效', '无效', '待确认']
}
} catch (error) {
console.error('获取状态列表失败:', error)
// 默认状态选项
statusOptions.value = ['有效', '无效', '待确认']
}
}

// 项目改变事件
const handleProjectChange = (projectId) => {
// 重置学生选择
scoreForm.studentId = null
// 加载对应项目的学生
loadStudentOptions(projectId)
// 获取项目信息设置轮次选项
const project = projectOptions.value.find(p => p.id === projectId)
if (project) {
roundOptions.value = Array.from({ length: project.rounds }, (_, i) => ({
value: i + 1,
label: `第${i + 1}轮`
}))
// 设置默认单位和成绩类型
if (project.type === '径赛') {
scoreForm.unit = '秒'
scoreForm.scoreType = 'time'
} else if (project.type === '田赛') {
scoreForm.unit = '米'
scoreForm.scoreType = 'distance'
}
}
}

// 成绩类型改变事件
const handleScoreTypeChange = (scoreType) => {
// 根据成绩类型设置默认单位
if (scoreType === 'time') {
scoreForm.unit = '秒'
} else if (scoreType === 'distance') {
scoreForm.unit = '米'
} else if (scoreType === 'score') {
scoreForm.unit = '分'
} else if (scoreType === 'ranking') {
scoreForm.unit = '名'
}
}

// 获取成绩步长
const getScoreStep = () => {
if (scoreForm.scoreType === 'time' || scoreForm.unit === '秒') {
return 0.01
}
return 0.01
}

// 项目筛选改变事件
const handleProjectFilterChange = (projectId) => {
if (projectId) {
const project = projectOptions.value.find(p => p.id === projectId)
if (project) {
roundOptions.value = Array.from({ length: project.rounds }, (_, i) => ({
value: i + 1,
label: `第${i + 1}轮`
}))
}
}
}

// 加载表格数据
const loadTableData = async () => {
tableLoading.value = true
try {
// 处理日期范围
const params = { ...searchForm }
if (params.dateRange && params.dateRange.length === 2) {
params.startDate = params.dateRange[0]
params.endDate = params.dateRange[1]
}
delete params.dateRange

const response = await getScorePage(pagination.currentPage, pagination.pageSize, params)

if (response.code === 200) {
tableData.value = response.data.records
pagination.total = response.data.total
} else {
ElMessage.error(response.message || '获取数据失败')
}
} catch (error) {
console.error('获取成绩数据失败:', error)
ElMessage.error('获取数据失败')
} finally {
tableLoading.value = false
}
}

// 搜索
const handleSearch = () => {
pagination.currentPage = 1
loadTableData()
}

// 重置搜索
const handleResetSearch = () => {
Object.assign(searchForm, {
projectId: null,
studentName: '',
status: '',
round: null,
scoreType: '',
isRecordBroken: '',
dateRange: null,
sortBy: '',
sortOrder: ''
})
handleSearch()
}

// 刷新
// eslint-disable-next-line no-unused-vars
const handleRefresh = () => {
loadTableData()
}

// 分页大小改变
const handleSizeChange = (val) => {
pagination.pageSize = val
loadTableData()
}

// 当前页改变
const handleCurrentChange = (val) => {
pagination.currentPage = val
loadTableData()
}

// 表格排序改变
const handleSortChange = ({ prop, order }) => {
searchForm.sortBy = prop
searchForm.sortOrder = order === 'ascending' ? 'asc' : order === 'descending' ? 'desc' : ''
loadTableData()
}

// 表格选择改变
const handleSelectionChange = (selection) => {
selectedScores.value = selection
}

// 添加成绩
// eslint-disable-next-line no-unused-vars
const handleAdd = () => {
isEdit.value = false
resetScoreForm()
dialogVisible.value = true
}

// 编辑成绩
const handleEdit = async (row) => {
isEdit.value = true
try {
const response = await getScoreById(row.id)
if (response.code === 200) {
Object.assign(scoreForm, response.data)
// 加载对应项目的学生
await loadStudentOptions(scoreForm.projectId)
// 设置轮次选项
const project = projectOptions.value.find(p => p.id === scoreForm.projectId)
if (project) {
roundOptions.value = Array.from({ length: project.rounds }, (_, i) => ({
value: i + 1,
label: `第${i + 1}轮`
}))
}
dialogVisible.value = true
} else {
ElMessage.error(response.message || '获取成绩信息失败')
}
} catch (error) {
console.error('获取成绩信息失败:', error)
ElMessage.error('获取成绩信息失败')
}
}

// 查看成绩详情
const handleViewDetail = async (row) => {
try {
const response = await getScoreById(row.id)
if (response.code === 200) {
currentScoreDetail.value = response.data
detailDialogVisible.value = true
} else {
ElMessage.error(response.message || '获取成绩详情失败')
}
} catch (error) {
console.error('获取成绩详情失败:', error)
ElMessage.error('获取成绩详情失败')
}
}

// 查看项目详情
const handleViewProjectDetail = (project) => {
// 可以打开项目详情对话框或跳转到项目详情页
ElMessage.info(`查看项目: ${project.name}`)
}

// 查看学生详情
const handleViewStudentDetail = (student) => {
// 可以打开学生详情对话框或跳转到学生详情页
ElMessage.info(`查看学生: ${student.realName}`)
}

// 查看成绩历史
const handleViewHistory = async (row) => {
try {
const response = await getScoreHistory(row.id)
if (response.code === 200) {
scoreHistory.value = response.data
historyDialogVisible.value = true
} else {
ElMessage.error(response.message || '获取历史记录失败')
}
} catch (error) {
console.error('获取历史记录失败:', error)
ElMessage.error('获取历史记录失败')
}
}

// 提交表单
const handleSubmit = () => {
if (!scoreFormRef.value) return

scoreFormRef.value.validate(async (valid) => {
if (valid) {
submitLoading.value = true
try {
let response
if (isEdit.value) {
response = await updateScore(scoreForm)
} else {
response = await addScore(scoreForm)
}

if (response.code === 200) {
ElMessage.success(isEdit.value ? '更新成功' : '录入成功')
handleDialogClose()
loadTableData()
} else {
ElMessage.error(response.message || (isEdit.value ? '更新失败' : '录入失败'))
}
} catch (error) {
console.error('保存成绩失败:', error)
ElMessage.error(isEdit.value ? '更新失败' : '录入失败')
} finally {
submitLoading.value = false
}
}
})
}

// 删除成绩
const handleDelete = (row) => {
ElMessageBox.confirm('确定要删除该成绩记录吗？', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
try {
const response = await deleteScore(row.id)
if (response.code === 200) {
ElMessage.success('删除成功')
loadTableData()
} else {
ElMessage.error(response.message || '删除失败')
}
} catch (error) {
console.error('删除成绩失败:', error)
ElMessage.error('删除失败')
}
})
}

// 批量删除
const handleBatchDelete = () => {
ElMessageBox.confirm(`确定要删除选中的 ${selectedScores.value.length} 条成绩记录吗？`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
batchLoading.value = true
try {
const scoreIds = selectedScores.value.map(score => score.id)
const response = await batchDeleteScores(scoreIds)
if (response.code === 200) {
ElMessage.success('批量删除成功')
loadTableData()
selectedScores.value = []
} else {
ElMessage.error(response.message || '批量删除失败')
}
} catch (error) {
console.error('批量删除失败:', error)
ElMessage.error('批量删除失败')
} finally {
batchLoading.value = false
}
})
}

// 批量审核
const handleBatchAudit = (status) => {
ElMessageBox.confirm(`确定要将选中的 ${selectedScores.value.length} 条成绩状态更改为"${status}"吗？`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
batchLoading.value = true
try {
const scoreIds = selectedScores.value.map(score => score.id)
const response = await batchAuditScores({ scoreIds, status })
if (response.code === 200) {
ElMessage.success('批量审核成功')
loadTableData()
selectedScores.value = []
} else {
ElMessage.error(response.message || '批量审核失败')
}
} catch (error) {
console.error('批量审核失败:', error)
ElMessage.error('批量审核失败')
} finally {
batchLoading.value = false
}
})
}

// 批量公示
const handleBatchPublish = () => {
ElMessageBox.confirm(`确定要公示选中的 ${selectedScores.value.length} 条成绩吗？`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
batchLoading.value = true
try {
const scoreIds = selectedScores.value.map(score => score.id)
const response = await batchPublishScores(scoreIds)
if (response.code === 200) {
ElMessage.success('批量公示成功')
loadTableData()
selectedScores.value = []
} else {
ElMessage.error(response.message || '批量公示失败')
}
} catch (error) {
console.error('批量公示失败:', error)
ElMessage.error('批量公示失败')
} finally {
batchLoading.value = false
}
})
}

// 批量录入
const handleBatchRecord = () => {
resetBatchRecordForm()
batchRecordDialogVisible.value = true
}

// 批量项目改变事件
const handleBatchProjectChange = async (projectId) => {
if (!projectId) {
batchStudentOptions.value = []
batchRecordForm.scores = []
return
}

try {
const response = await getEnrollmentsByProjectId(projectId)
if (response.code === 200) {
batchStudentOptions.value = response.data.map(enrollment => enrollment.student)
// 获取项目信息设置轮次选项和默认单位
const project = projectOptions.value.find(p => p.id === projectId)
if (project) {
roundOptions.value = Array.from({ length: project.rounds }, (_, i) => ({
value: i + 1,
label: `第${i + 1}轮`
}))
// 设置默认单位
if (project.type === '径赛') {
batchRecordForm.unit = '秒'
} else if (project.type === '田赛') {
batchRecordForm.unit = '米'
}
}
}
} catch (error) {
console.error('获取学生列表失败:', error)
batchStudentOptions.value = []
}
}

// 批量学生改变事件
// eslint-disable-next-line no-unused-vars
const handleBatchStudentChange = (_row) => {
// 可以在这里添加学生改变的逻辑
}

// 添加批量成绩
const handleAddBatchScore = () => {
batchRecordForm.scores.push({
studentId: null,
scoreValue: null,
ranking: null,
isRecordBroken: false,
remark: ''
})
}

// 移除批量成绩
const handleRemoveBatchScore = (index) => {
batchRecordForm.scores.splice(index, 1)
}

// 提交批量录入
const handleBatchRecordSubmit = () => {
if (!batchRecordFormRef.value) return

batchRecordFormRef.value.validate(async (valid) => {
if (valid) {
// 验证批量录入数据
if (batchRecordForm.scores.length === 0) {
ElMessage.warning('请至少添加一条成绩记录')
return
}

// 验证每个成绩记录
const validScores = batchRecordForm.scores.every(score =>
score.studentId && score.scoreValue !== null
)

if (!validScores) {
ElMessage.warning('请完整填写所有成绩记录')
return
}

batchSubmitLoading.value = true
try {
const scores = batchRecordForm.scores.map(score => ({
projectId: batchRecordForm.projectId,
studentId: score.studentId,
round: batchRecordForm.round,
scoreValue: score.scoreValue,
unit: batchRecordForm.unit,
ranking: score.ranking,
isRecordBroken: score.isRecordBroken,
status: '有效',
remark: score.remark
}))

// 批量提交成绩
const promises = scores.map(score => addScore(score))
await Promise.all(promises)

ElMessage.success('批量录入成功')
handleBatchRecordDialogClose()
loadTableData()
} catch (error) {
console.error('批量录入失败:', error)
ElMessage.error('批量录入失败')
} finally {
batchSubmitLoading.value = false
}
}
})
}

// 导出模板
const handleExportTemplate = async () => {
exportLoading.value = true
try {
const response = await exportScoreTemplate()
// 创建下载链接
const blob = new Blob([response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
const url = window.URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = '成绩导入模板.xlsx'
a.click()
window.URL.revokeObjectURL(url)
ElMessage.success('模板下载成功')
} catch (error) {
console.error('导出模板失败:', error)
ElMessage.error('导出模板失败')
} finally {
exportLoading.value = false
}
}

// 批量导入
const handleBatchImport = () => {
importDialogVisible.value = true
fileList.value = []
}

// 文件改变事件
const handleFileChange = (file) => {
fileList.value = [file]
}

// 上传前验证
const beforeUpload = (file) => {
const isExcel = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
file.type === 'application/vnd.ms-excel'
    const isLt10M = file.size / 1024 / 1024 < 10

if (!isExcel) {
ElMessage.error('只能上传Excel文件!')
return false
}
if (!isLt10M) {
ElMessage.error('文件大小不能超过10MB!')
return false
}
return false // 阻止自动上传
}

// 提交上传
const submitUpload = () => {
if (fileList.value.length === 0) {
ElMessage.error('请选择要上传的文件')
return
}

uploadLoading.value = true
const formData = new FormData()
formData.append('file', fileList.value[0].raw)

batchImportScores(formData).then(response => {
if (response.code === 200) {
ElMessage.success('导入成功')
handleImportDialogClose()
loadTableData()
} else {
ElMessage.error(response.message || '导入失败')
}
}).catch(error => {
console.error('导入失败:', error)
ElMessage.error('导入失败')
}).finally(() => {
uploadLoading.value = false
})
}

// 关闭对话框
const handleDialogClose = () => {
dialogVisible.value = false
if (scoreFormRef.value) {
scoreFormRef.value.resetFields()
}
}

// 关闭批量录入对话框
const handleBatchRecordDialogClose = () => {
batchRecordDialogVisible.value = false
resetBatchRecordForm()
}

// 关闭导入对话框
const handleImportDialogClose = () => {
importDialogVisible.value = false
fileList.value = []
uploadLoading.value = false
}

// 重置成绩表单
const resetScoreForm = () => {
Object.assign(scoreForm, {
id: null,
projectId: null,
studentId: null,
round: 1,
scoreValue: null,
scoreType: 'time',
unit: '秒',
status: '有效',
ranking: null,
isRecordBroken: false,
remark: ''
})
studentOptions.value = []
roundOptions.value = []
if (scoreFormRef.value) {
scoreFormRef.value.resetFields()
}
}

// 重置批量录入表单
const resetBatchRecordForm = () => {
Object.assign(batchRecordForm, {
projectId: null,
round: 1,
unit: '秒',
scores: []
})
batchStudentOptions.value = []
roundOptions.value = []
if (batchRecordFormRef.value) {
batchRecordFormRef.value.resetFields()
}
}

// 退出登录
const handleLogout = () => {
ElMessageBox.confirm('确定要退出登录吗？', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 清除用户信息
if (store && store.commit) {
  store.commit('clearUser')
}
localStorage.removeItem('user')
localStorage.removeItem('token')
// 跳转到登录页
router.push('/login')
})
}

// 导航到指定路径
const navigateTo = (path) => {
router.push(path)
}

// 获取状态标签类型
const getStatusTagType = (status) => {
const statusMap = {
'有效': 'success',
'无效': 'danger',
'待确认': 'warning'
}
return statusMap[status] || 'info'
}

// 获取项目类型标签类型
const getTypeTagType = (type) => {
const typeMap = {
'径赛': 'primary',
'田赛': 'success',
'球类': 'warning',
'其他': 'info'
}
return typeMap[type] || 'primary'
}

// 获取成绩类型标签类型
const getScoreTypeTagType = (scoreType) => {
const typeMap = {
'time': 'primary',
'distance': 'success',
'score': 'warning',
'ranking': 'info'
}
return typeMap[scoreType] || 'info'
}

// 获取成绩类型标签文本
const getScoreTypeLabel = (scoreType) => {
const typeMap = {
'time': '时间',
'distance': '距离',
'score': '得分',
'ranking': '名次'
}
return typeMap[scoreType] || scoreType
}

// 获取排名标签类型
const getRankingTagType = (ranking) => {
if (ranking === 1) return 'danger' // 金牌
if (ranking === 2) return 'warning' // 银牌
if (ranking === 3) return 'success' // 铜牌
return 'info'
}

// 格式化日期时间
const formatDateTime = (dateTime) => {
if (!dateTime) return '-'
return new Date(dateTime).toLocaleString('zh-CN')
}

// 生命周期钩子
onMounted(() => {
// 设置表格高度
setTableHeight()
window.addEventListener('resize', setTableHeight)

// 初始化数据
initData()
})

// 组件卸载时移除事件监听
onBeforeUnmount(() => {
window.removeEventListener('resize', setTableHeight)
})
</script>

<style scoped>
/* 基础样式 */
* {
font-family: 'PingFang SC', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
box-sizing: border-box;
}

/* 全局变量 */
:root {
--primary-color: #2C5AA0;
--primary-light: #E8EFF9;
--primary-dark: #1E3D73;
--success-color: #67C23A;
--warning-color: #E6A23C;
--danger-color: #F56C6C;
--info-color: #909399;
--text-primary: #303133;
--text-regular: #606266;
--text-secondary: #909399;
--text-placeholder: #C0C4CC;
--border-light: #EBEEF5;
--border-base: #DCDFE6;
--border-lighter: #F2F6FC;
--background-base: #F5F7FA;
--background-light: #FAFAFA;
}

/* 容器布局 */
.app-container {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr;
min-height: 100vh;
background-color: var(--background-base);
}

/* 顶部导航栏 */
.header {
grid-column: 1 / -1;
background-color: var(--primary-color);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
position: relative;
z-index: 100;
}

.logo {
font-size: 20px;
font-weight: 600;
color: white;
display: flex;
align-items: center;
gap: 12px;
letter-spacing: 0.5px;
}

.flex-grow {
flex-grow: 1;
}

/* 用户信息区域 */
.user-info {
display: flex;
align-items: center;
}

.user-avatar {
display: flex;
align-items: center;
gap: 12px;
cursor: pointer;
padding: 8px 12px;
border-radius: 6px;
transition: background-color 0.3s;
}

.user-avatar:hover {
background-color: rgba(255, 255, 255, 0.1);
}

.username {
color: white;
font-size: 14px;
font-weight: 500;
}

/* 左侧导航栏 */
.sidebar {
background-color: white;
padding: 16px 0;
border-right: 1px solid var(--border-light);
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.05);
overflow-y: auto;
}

.menu-item {
padding: 14px 24px;
color: var(--text-regular);
display: flex;
align-items: center;
gap: 12px;
transition: all 0.3s ease;
cursor: pointer;
font-weight: 500;
position: relative;
}

.menu-item:hover {
background-color: var(--primary-light);
color: var(--primary-color);
}

.menu-item.active {
background-color: var(--primary-light);
color: var(--primary-color);
}

.menu-item.active::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 4px;
background-color: var(--primary-color);
}

.menu-item span {
font-size: 15px;
}

/* 主内容区 */
.content {
padding: 24px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 24px;
}

/* 页面标题区域 */
.page-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
flex-wrap: wrap;
gap: 16px;
}

.page-title h1 {
font-size: 28px;
font-weight: 600;
color: var(--text-primary);
margin: 0 0 8px 0;
}

.page-desc {
font-size: 14px;
color: var(--text-secondary);
margin: 0;
}

.header-actions {
display: flex;
gap: 12px;
align-items: center;
flex-wrap: wrap;
}

/* 搜索卡片 */
.search-card {
margin-bottom: 0;
}

.search-card :deep(.el-card__body) {
padding: 24px;
}

.advanced-search {
margin-top: 20px;
}

/* 表格卡片 */
.table-card {
flex: 1;
display: flex;
flex-direction: column;
}

.table-card :deep(.el-card__body) {
padding: 0;
flex: 1;
display: flex;
flex-direction: column;
}

/* 表格工具栏 */
.table-toolbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 24px;
border-bottom: 1px solid var(--border-light);
}

.table-info {
display: flex;
align-items: center;
gap: 12px;
}

.table-title {
font-size: 16px;
font-weight: 600;
color: var(--text-primary);
}

.table-actions {
display: flex;
align-items: center;
gap: 12px;
}

/* 表格样式 */
:deep(.el-table) {
flex: 1;
font-size: 14px;
}

:deep(.el-table th) {
background-color: var(--background-light) !important;
color: var(--text-primary);
font-weight: 600;
}

:deep(.el-table td) {
padding: 12px 0;
}

:deep(.el-table .el-table__row:hover > td) {
background-color: var(--primary-light);
}

/* 成绩值样式 */
.score-value {
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
}

.score-value .value {
font-weight: 600;
font-size: 16px;
}

.score-value .unit {
font-size: 12px;
color: var(--text-secondary);
}

/* 排名样式 */
.ranking {
display: flex;
align-items: center;
justify-content: center;
}

.no-ranking {
color: var(--text-placeholder);
}

/* 表格操作按钮组 */
:deep(.el-button-group .el-button) {
margin-left: 0;
}

:deep(.el-button-group .el-button + .el-button) {
margin-left: 1px;
}

/* 分页容器 */
.pagination-container {
padding: 16px 24px;
display: flex;
justify-content: flex-end;
border-top: 1px solid var(--border-light);
}

/* 批量操作栏 */
.batch-operations {
padding: 16px 24px;
background-color: var(--primary-light);
border-top: 1px solid var(--border-light);
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 12px;
}

.batch-info {
display: flex;
align-items: center;
gap: 8px;
font-weight: 500;
color: var(--primary-color);
}

.batch-actions {
display: flex;
gap: 12px;
flex-wrap: wrap;
}

/* 对话框样式 */
:deep(.el-dialog) {
border-radius: 8px;
overflow: hidden;
}

:deep(.el-dialog__header) {
background-color: var(--primary-color);
color: white;
padding: 20px 24px;
}

:deep(.el-dialog__title) {
color: white;
font-weight: 600;
}

:deep(.el-dialog__headerbtn .el-dialog__close) {
color: white;
}

:deep(.el-dialog__body) {
padding: 24px;
}

:deep(.el-dialog__footer) {
padding: 16px 24px;
border-top: 1px solid var(--border-light);
}

/* 表单样式 */
:deep(.el-form-item__label) {
font-weight: 500;
color: var(--text-primary);
}

:deep(.el-input__inner) {
border-radius: 4px;
}

:deep(.el-select .el-input .el-input__inner) {
border-radius: 4px;
}

/* 成绩详情样式 */
.score-detail {
padding: 8px 0;
}

.remark-content {
line-height: 1.6;
color: var(--text-regular);
}

:deep(.el-descriptions__label) {
font-weight: 600;
}

:deep(.el-descriptions__content) {
color: var(--text-regular);
}

/* 导入内容样式 */
.import-content {
padding: 20px 0;
}

/* 按钮激活状态 */
:deep(.el-button.is-active) {
background-color: var(--primary-color);
border-color: var(--primary-color);
color: white;
}

/* 消息提示样式 */
:deep(.el-message) {
border-radius: 4px;
}

:deep(.el-message-box) {
border-radius: 8px;
}


/* 动画效果 */
.el-fade-in-enter-active,
.el-fade-in-leave-active {
transition: opacity 0.3s ease;
}

.el-fade-in-enter-from,
.el-fade-in-leave-to {
opacity: 0;
}

.el-zoom-in-enter-active,
.el-zoom-in-leave-active {
transition: all 0.3s ease;
}

.el-zoom-in-enter-from,
.el-zoom-in-leave-to {
transform: scale(0.9);
opacity: 0;
}

/* 自定义滚动条 */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}

::-webkit-scrollbar-track {
background: var(--background-light);
border-radius: 4px;
}

::-webkit-scrollbar-thumb {
background: var(--border-base);
border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
background: var(--text-placeholder);
}
</style>